home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / 2x2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  8.7 KB  |  378 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include <config.h>
  23. #include "video.h"
  24. #include "dither.h"
  25. #include "proto.h"
  26.  
  27. #define RAND_ERR_RANGE 7
  28. #define RAND_ERR_SUBVAL 3
  29.  
  30. /* Array containing actual pixel values for each possible 2x2 dither pattern. */
  31.  
  32. static unsigned char *dith_a;
  33.  
  34. /* Arrays mapping lum, cr, and cb values to portions of dither pattern code. 
  35.    The addtion of one value from each array yields a valid dither pattern
  36.    code.
  37. */
  38.  
  39. static int lval_a[256+RAND_ERR_RANGE-1];
  40. static int rval_a[256+RAND_ERR_RANGE-1];
  41. static int bval_a[256+RAND_ERR_RANGE-1];
  42.  
  43. /* Range of possible dither patterns in each channel. */
  44.  
  45. #define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
  46. #define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
  47. #define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
  48.  
  49. /* Arrays of random error terms added to break up contours. */
  50.  
  51. static int *randval_a;
  52. static int **randptr_a;
  53.  
  54.  
  55. /*
  56.  *--------------------------------------------------------------
  57.  *
  58.  *  Init2x2Dither--
  59.  *
  60.  *    Initializes structures used for 2x2 dithering.
  61.  *
  62.  * Results:
  63.  *    None.
  64.  *
  65.  * Side effects:
  66.  *    None.
  67.  *
  68.  *--------------------------------------------------------------
  69.  */
  70.  
  71. void
  72. Init2x2Dither()
  73. {  
  74.   unsigned char *dith_ca;
  75.   int numcodes;
  76.   int l_range, cr_range, cb_range;
  77.   int p1, p2, p3, p4;
  78.   int l_dith, cr_dith, cb_dith;
  79.   int big_part, small_part;
  80.   int i, j;
  81.  
  82.   l_range = L_DITH_RANGE;
  83.   cr_range = CR_DITH_RANGE;
  84.   cb_range = CB_DITH_RANGE;
  85.  
  86.   numcodes =  l_range * cr_range * cb_range;
  87.  
  88.   dith_a = (unsigned char *) malloc(numcodes*4);
  89.  
  90.   dith_ca =  dith_a;
  91.  
  92.   for (i=0; i<numcodes; i++) {
  93.     l_dith = i  % l_range;
  94.  
  95.     big_part = l_dith / 4;
  96.     small_part = l_dith % 4;
  97.  
  98.     p1 = big_part + ((small_part > 0) ? 1 : 0);
  99.     p2 = big_part + ((small_part > 2) ? 1 : 0);
  100.     p3 = big_part;
  101.     p4 = big_part + ((small_part > 1) ? 1 : 0);
  102.  
  103.     p1 *= CR_RANGE * CB_RANGE;
  104.     p2 *= CR_RANGE * CB_RANGE;
  105.     p3 *= CR_RANGE * CB_RANGE;
  106.     p4 *= CR_RANGE * CB_RANGE;
  107.  
  108.     cr_dith = (i/l_range) % cr_range;
  109.  
  110.     big_part = cr_dith / 4;
  111.     small_part = cr_dith % 4;
  112.  
  113.     p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
  114.     p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
  115.     p3 += (big_part)*CB_RANGE;
  116.     p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
  117.  
  118.     cb_dith = (i/(cr_range*l_range)) % cb_range;
  119.  
  120.     big_part = cb_dith / 4;
  121.     small_part = cb_dith % 4;
  122.  
  123.     p1 += (big_part + ((small_part > 0) ? 1 : 0));
  124.     p2 += (big_part + ((small_part > 2) ? 1 : 0));
  125.     p3 += (big_part);
  126.     p4 += (big_part + ((small_part > 1) ? 1 : 0));
  127.  
  128.     *dith_ca++ = p1;
  129.     *dith_ca++ = p2;
  130.     *dith_ca++ = p3;
  131.     *dith_ca++ = p4;
  132.   }
  133.  
  134.   for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
  135.     j = i-RAND_ERR_SUBVAL;
  136.     lval_a[i] = (j * L_DITH_RANGE)/256;
  137.     rval_a[i] = (j * CR_DITH_RANGE)/256;
  138.     bval_a[i] = (j * CB_DITH_RANGE)/256;
  139.  
  140.     bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
  141.     rval_a[i] *= L_DITH_RANGE * 4;
  142.     lval_a[i] *= 4;
  143.   }
  144.  
  145.   for (i=0; i<RAND_ERR_SUBVAL; i++) {
  146.     lval_a[i] = lval_a[RAND_ERR_SUBVAL];
  147.     rval_a[i] = rval_a[RAND_ERR_SUBVAL];
  148.     bval_a[i] = bval_a[RAND_ERR_SUBVAL];
  149.   }
  150.  
  151.    for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
  152.      lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
  153.      rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
  154.      bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
  155.    }
  156. }
  157.  
  158.  
  159. /*
  160.  *--------------------------------------------------------------
  161.  *
  162.  * RandInit --
  163.  *
  164.  *    Initializes the random values used for 2x2 dithering.
  165.  *
  166.  * Results:
  167.  *    randval_a filled with random values.
  168.  *      randptr_a filled with random pointers to random value arrays.
  169.  *
  170.  * Side effects:
  171.  *      None.
  172.  *
  173.  *--------------------------------------------------------------
  174.  */
  175.  
  176. void RandInit(h, w)
  177.      int h, w;
  178. {
  179.   int i;
  180.  
  181.   randval_a = (int *) malloc(w*5*sizeof(int));
  182.   randptr_a = (int **) malloc(h*sizeof(int *));
  183.  
  184. #if (! HAVE_LRAND48)
  185.   for (i=0; i<w*5; i++) {
  186.     long int random();
  187.  
  188.     randval_a[i] = random() % RAND_ERR_RANGE;
  189.   }
  190.  
  191.   for (i=0; i<h; i++) {
  192.     long int random();
  193.  
  194.     randptr_a[i] = randval_a + (random() % (w*2));
  195.   }
  196. #else /* HAVE_LRAND48 */
  197.  
  198.   for (i=0; i<w*5; i++) {
  199.     long int lrand48();
  200.     
  201.     randval_a[i] = lrand48() % RAND_ERR_RANGE;
  202.   }
  203.   
  204.   for (i=0; i<h; i++) {
  205.     long int lrand48();
  206.  
  207.     randptr_a[i] = randval_a + (lrand48() % (w*2));
  208.   }
  209. #endif
  210.   
  211. }
  212.  
  213.  
  214. /*
  215.  *--------------------------------------------------------------
  216.  *
  217.  *  PostInit2x2Dither--
  218.  *
  219.  *    Remaps color numbers in dither patterns to actual pixel
  220.  *      values allocated by the X server.
  221.  *
  222.  * Results:
  223.  *      None.
  224.  *
  225.  * Side effects:
  226.  *      None.
  227.  *
  228.  *--------------------------------------------------------------
  229.  */
  230.  
  231. void
  232. PostInit2x2Dither() 
  233. {
  234.   unsigned char *dith_ca;
  235.   int i;
  236.  
  237.   dith_ca = dith_a;
  238.  
  239.   for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
  240.     
  241.     *dith_ca = pixel[*dith_ca];
  242.     dith_ca++;
  243.     *dith_ca = pixel[*dith_ca];
  244.     dith_ca++;
  245.     *dith_ca = pixel[*dith_ca];
  246.     dith_ca++;
  247.     *dith_ca = pixel[*dith_ca];
  248.     dith_ca++;
  249.   }
  250. }
  251.  
  252.  
  253. /*
  254.  *--------------------------------------------------------------
  255.  *
  256.  * Twox2DitherImage --
  257.  *
  258.  *    Dithers lum, cr, and cb channels togethor using predefined
  259.  *      and computed 2x2 dither patterns. Each possible combination of
  260.  *      lum, cr, and cb values combines to point to a particular dither
  261.  *      pattern (2x2) which is used to represent the pixel. This assumes
  262.  *      That the display plane is 4 times larger than the lumianance 
  263.  *      plane. 
  264.  *
  265.  * Results:
  266.  *      None.
  267.  *
  268.  * Side effects:
  269.  *      None.
  270.  *
  271.  *--------------------------------------------------------------
  272.  */
  273.  
  274. void 
  275. Twox2DitherImage(lum, cr, cb, out, h, w)
  276.     unsigned char *lum;
  277.     unsigned char *cr;
  278.     unsigned char *cb;
  279.     unsigned char *out;
  280.     int w, h;
  281. {
  282.   int i, j;
  283.   unsigned short *o1, *o2, *o3, *o4;
  284.   unsigned char *l1, *l2, *base;
  285.   unsigned char B, R;
  286.   unsigned short *dith_ca;
  287.   int big_adv = 3*w;
  288.   int b_val, r_val, l_val;
  289.   int *randvalptr;
  290.   int randval;
  291.   static int first = 1;
  292.  
  293.   if (first) {
  294.     RandInit(h, w);
  295.     first = 0;
  296.   }
  297.  
  298.   o1 = (unsigned short *)out;
  299.   o2 = (unsigned short *)(out+(2*w));
  300.   o3 = (unsigned short *)(out+(4*w));
  301.   o4 = (unsigned short *)(out+(6*w));
  302.   l1 = lum;
  303.   l2 = lum+w;
  304.  
  305.   for (i=0; i<h; i+=2) {
  306.     for(j=0; j<w; j+= 4) {
  307.  
  308.       B = cb[0];
  309.       b_val = bval_a[B];
  310.       R = cr[0];
  311.       r_val = rval_a[R];
  312.       base = dith_a + b_val + r_val;
  313.  
  314.       l_val = lval_a[l1[0]];
  315.       dith_ca = (unsigned short *)(base + l_val);
  316.       o1[0] = dith_ca[0];
  317.       o2[0] = dith_ca[1];
  318.  
  319.       l_val = lval_a[l1[1]];
  320.       dith_ca = (unsigned short *)(base + l_val);
  321.       o1[1] = dith_ca[0];
  322.       o2[1] = dith_ca[1];
  323.  
  324.       l_val = lval_a[l2[0]];
  325.       dith_ca = (unsigned short *)(base + l_val);
  326.       o3[0] = dith_ca[0];
  327.       o4[0] = dith_ca[1];
  328.  
  329.       l_val = lval_a[l2[1]];
  330.       dith_ca = (unsigned short *)(base + l_val);
  331.       o3[1] = dith_ca[0];
  332.       o4[1] = dith_ca[1];
  333.  
  334.       B = cb[1];
  335.       b_val = bval_a[B];
  336.       R = cr[1];
  337.       r_val = rval_a[R];
  338.       base = dith_a + b_val + r_val;
  339.  
  340.       l_val = lval_a[l1[2]];
  341.       dith_ca = (unsigned short *)(base + l_val);
  342.       o1[2] = dith_ca[0];
  343.       o2[2] = dith_ca[1];
  344.  
  345.       l_val = lval_a[l1[3]];
  346.       dith_ca = (unsigned short *)(base + l_val);
  347.       o1[3] = dith_ca[0];
  348.       o2[3] = dith_ca[1];
  349.  
  350.       l_val = lval_a[l2[2]];
  351.       dith_ca = (unsigned short *)(base + l_val);
  352.       o3[2] = dith_ca[0];
  353.       o4[2] = dith_ca[1];
  354.  
  355.       l_val = lval_a[l2[3]];
  356.       dith_ca = (unsigned short *)(base + l_val);
  357.       o3[3] = dith_ca[0];
  358.       o4[3] = dith_ca[1];
  359.  
  360.       o1 += 4;
  361.       o2 += 4;
  362.       o3 += 4;
  363.       o4 += 4;
  364.       l1 += 4;
  365.       l2 += 4;
  366.       cb += 2;
  367.       cr += 2;
  368.     }    
  369.  
  370.     l1 += w;
  371.     l2 += w;
  372.     o1 += big_adv;
  373.     o2 += big_adv;
  374.     o3 += big_adv;
  375.     o4 += big_adv;
  376.   }
  377. }
  378.